package top.codedance.iotp.common.util;

import top.codedance.iotp.common.entity.CliCmdEntity;
import org.apache.commons.cli.*;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;

public class CommandCli {
    private CommandLine line = null;

    public CommandCli(String[] args, List<CliCmdEntity> opts) {
        CommandLineParser parser = new DefaultParser();

        Options options = new Options();

        for (CliCmdEntity cliCmdEntity : opts) {
            options.addOption(Option.builder(
                    cliCmdEntity.getShortOpt()) //短key
                            .longOpt(cliCmdEntity.getLongOpt()) //长key
                            .hasArg(cliCmdEntity.isHasArg()) //是否含有参数
                            .argName(cliCmdEntity.getLongOpt()) //参数值的名称
                            .required(cliCmdEntity.isRequired()) //命令行中必须包含此 option
                            .desc(cliCmdEntity.getDescription()) //描述
                            .optionalArg(true) //参数的值是否可选
//                    .numberOfArgs(3) //指明参数有多少个参数值
                            .hasArgs() //无限制参数值个数
                            .valueSeparator(',')// 参数值的分隔符
                            .type(cliCmdEntity.getType()) //参数值的类型
                            .build()
            );
        }

        try {
            line = parser.parse(options, args);
        } catch (ParseException exp) {
            System.out.println("Programe parameters is error, Shutdown ...");
            Collection<Option> os = options.getOptions();
            for (Option o : os) {
                System.out.println(" -" + o.getOpt() + " or --" + o.getArgName() + ": [" + (o.isRequired() ? "MUST" : "NOT MUST") + "] " + o.getDescription());
            }
            System.exit(0);
        }
    }

    public <T> T getArg(String argName) {
        return getArg(argName, null);
    }

    public <T> T getArg(String argName, T defaultValue) {
        if (line != null && line.hasOption(argName)) {
            String optionValue = line.getOptionValue(argName);
            if (defaultValue instanceof Short) {
                return (T) new Short(Short.parseShort(optionValue));
            }
            if (defaultValue instanceof Integer) {
                return (T) new Integer(Integer.parseInt(optionValue));
            }
            if (defaultValue instanceof Long) {
                return (T) new Long(Long.parseLong(optionValue));
            }
            if (defaultValue instanceof Boolean) {
                return (T) new Boolean(true);
            }
            return (T) optionValue;
        } else {
            return defaultValue;
        }
    }

    public boolean hasArg(String srgName) {
        boolean isHas = false;
        Iterator<Option> iterator = line.iterator();
        while (iterator.hasNext()){
            Option next = iterator.next();
            if(next.getLongOpt().equals(srgName) || next.getOpt().equals(srgName)){
                isHas = next.hasArg();
                break;
            }
        }
        return isHas;
    }
}
